package cn.bqjr.eily.shiro.spring.boot;

import cn.bqjr.eily.shiro.spring.boot.entity.ShiroProperties;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;

@Component
public class RedisShiroSessionDAO extends AbstractSessionDAO {

    private static Logger logger = LoggerFactory.getLogger(RedisShiroSessionDAO.class);

    @Autowired
    private ShiroProperties shiroProperties;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private BoundHashOperations<String, Serializable, Session> sessionOperation;

    @PostConstruct
    public void initSessionOperation() {
        this.sessionOperation = redisTemplate.boundHashOps(shiroProperties.getRedis().getSessionPrefix());
    }

    private void saveSession(Session session) throws UnknownSessionException {
        if (session != null && session.getId() != null) {
            logger.debug("保存session:{}", session.getId());
            session.setTimeout(shiroProperties.getSessionManager().getGlobalSessionTimeout());
            sessionOperation.put(session.getId(), session);
        }
    }

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = this.generateSessionId(session);
        logger.debug("创建session:{}", sessionId);
        this.assignSessionId(session, sessionId);
        this.saveSession(session);
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        if (null != sessionId) {
            logger.debug("获取session:{}", sessionId);
            return sessionOperation.get(sessionId);
        }
        return null;
    }

    @Override
    public void update(Session session) throws UnknownSessionException {
        this.saveSession(session);
    }

    @Override
    public void delete(Session session) {
        logger.debug("删除session:{}", session.getId());
        sessionOperation.delete(session.getId());
    }

    @Override
    public Collection<Session> getActiveSessions() {
        List<Session> sessions = sessionOperation.values();
        logger.debug("获取在线session数:{}", sessions.size());
        return sessions;
    }
}
